package com.cweb.framework.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cweb.framework.pojo.CustomException;
import com.cweb.framework.pojo.PageParam;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Set;

public class MybatisUtil {
    // 基本的共通查询条件
    public static <T> QueryWrapper initCondQueryWrapper(T entity) {
        QueryWrapper cond = new QueryWrapper(entity);
        cond.eq("`status`", MyConstant.database.DATA_COMM_STATUS_SUCCESS);
        cond.orderByDesc("update_time");
        return cond;
    }

    public static <T> QueryWrapper initCondQueryWrapper_timeDesc(T entity) {
        QueryWrapper cond = new QueryWrapper(entity);
        cond.orderByDesc("create_time");
        return cond;
    }

    // 基本的分页条件
    public static Page initCondPage(PageParam pageParam) {
        Page page = new Page(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getPageCount());
        // 已传入count数时，不在count
        if (page.getTotal() > 0L || page.getSize() == 0 || page.getSize() == 1) {
            page.setSearchCount(false);
        }
        return page;
    }

    // 基本创建对象
    public static <T> T initNewObj(T entity) {
        Set<String> setMethod = ReflectUtil.getPublicMethodNames(entity.getClass());
        if (setMethod.contains("setStatus")) {
            ReflectUtil.invoke(entity, "setStatus", MyConstant.database.DATA_COMM_STATUS_SUCCESS);
        }
        if (setMethod.contains("setCreateTime")) {
            Method method = ReflectUtil.getMethodByName(entity.getClass(), "setCreateTime");
            if (null != method && method.getParameterTypes().length > 0) {
                if ("java.util.Date".equals(method.getParameterTypes()[0].getName())) {
                    ReflectUtil.invoke(entity, "setCreateTime", new Date());
                }
                if ("java.time.Date".equals(method.getParameterTypes()[0].getName())) {
                    ReflectUtil.invoke(entity, "setCreateTime", new Date());
                }
            }
        }
        return entity;
    }

    // 处理的登录处理
    public static <T> void processLogin(T obj, T param) throws CustomException {
        // 用户信息验证
        if (null == obj) {
            throw new CustomException(ErrorEnum.USER_INFO_NO_FIND);
        }
        if (!MyConstant.database.DATA_COMM_STATUS_SUCCESS.equals(BeanUtil.getProperty(obj, "status"))) {
            throw new CustomException(ErrorEnum.USER_INFO_STATUS_ERROR);
        }
        if (!PasswordUtil.encryptPasswordAES((String) BeanUtil.getProperty(param, "password")).equals(BeanUtil.getProperty(obj, "password"))) {
            throw new CustomException(ErrorEnum.USER_INFO_PASSWORD_ERROR);
        }
        // 用户信息更新
        BeanUtil.setProperty(obj, "loginCount", null == BeanUtil.getProperty(obj, "loginCount") ? 1 : (Integer) BeanUtil.getProperty(obj, "loginCount") + 1);
        BeanUtil.setProperty(obj, "lastLoginTime", new Date());
    }

    /**
     * FOR UPDATE 查找id
     */
    public static <T> T getByIdForUpdate(IService<T> service, Long id) throws CustomException {
        QueryWrapper cond = new QueryWrapper();
        cond.eq("`id`", id);
        cond.last("FOR UPDATE");
        T ret = (T) service.getOne(cond);
        if (null == ret) {
            throw new CustomException(ErrorEnum.COMM_OBJ_NO_FIND);
        }
        return ret;
    }
}
